<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
    <title>Reference</title>
    <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>

<div id="container">

<div id="product">
	<div id="product_logo"></div>
	<div id="product_name"><big><b></b></big></div>
	<div id="product_description"></div>
</div> <!-- id="product" -->


<div id="main">


<!-- Menu -->

<div id="navigation">
<br/>
<h1>Duplex</h1>

<ul>
  <li><a href="../index.html">Index</a></li>
</ul>

<h2>Contents</h2>
<ul>
<li><a href="#Functions">Functions</a></li>
<li><a href="#Tables">Tables</a></li>
<li><a href="#Fields">Fields</a></li>
</ul>


<h2>Modules</h2>
<ul class="$(kind=='Topics' and '' or 'nowrap'">
  <li><a href="../modules/Duplex.Application.html">Duplex.Application</a></li>
  <li><a href="../modules/Duplex.Applications.Effect.html">Duplex.Applications.Effect</a></li>
  <li><a href="../modules/Duplex.Applications.GridPie.html">Duplex.Applications.GridPie</a></li>
  <li><a href="../modules/Duplex.Applications.Hydra.html">Duplex.Applications.Hydra</a></li>
  <li><a href="../modules/Duplex.Applications.Instrument.html">Duplex.Applications.Instrument</a></li>
  <li><a href="../modules/Duplex.Applications.Keyboard.GridLayout.html">Duplex.Applications.Keyboard.GridLayout</a></li>
  <li><a href="../modules/Duplex.Applications.Keyboard.Layouts.HarmonicLayout.html">Duplex.Applications.Keyboard.Layouts.HarmonicLayout</a></li>
  <li><a href="../modules/Duplex.Applications.Keyboard.Layouts.IsomorphicLayout.html">Duplex.Applications.Keyboard.Layouts.IsomorphicLayout</a></li>
  <li><a href="../modules/Duplex.Applications.Keyboard.Layouts.PianoLayout.html">Duplex.Applications.Keyboard.Layouts.PianoLayout</a></li>
  <li><strong>Duplex.Applications.Keyboard</strong></li>
  <li><a href="../modules/Duplex.Applications.Matrix.html">Duplex.Applications.Matrix</a></li>
  <li><a href="../modules/Duplex.Applications.Metronome.html">Duplex.Applications.Metronome</a></li>
  <li><a href="../modules/Duplex.Applications.MidiActions.Bindings.html">Duplex.Applications.MidiActions.Bindings</a></li>
  <li><a href="../modules/Duplex.Applications.MidiActions.html">Duplex.Applications.MidiActions</a></li>
  <li><a href="../modules/Duplex.Applications.Mixer.html">Duplex.Applications.Mixer</a></li>
  <li><a href="../modules/Duplex.Applications.Mlrx.Mlrx_group.html">Duplex.Applications.Mlrx.Mlrx_group</a></li>
  <li><a href="../modules/Duplex.Applications.Mlrx.Mlrx_note.html">Duplex.Applications.Mlrx.Mlrx_note</a></li>
  <li><a href="../modules/Duplex.Applications.Mlrx.Mlrx_pos.html">Duplex.Applications.Mlrx.Mlrx_pos</a></li>
  <li><a href="../modules/Duplex.Applications.Mlrx.Mlrx_track.html">Duplex.Applications.Mlrx.Mlrx_track</a></li>
  <li><a href="../modules/Duplex.Applications.Mlrx.html">Duplex.Applications.Mlrx</a></li>
  <li><a href="../modules/Duplex.Applications.Navigator.html">Duplex.Applications.Navigator</a></li>
  <li><a href="../modules/Duplex.Applications.NotesOnWheels.html">Duplex.Applications.NotesOnWheels</a></li>
  <li><a href="../modules/Duplex.Applications.PatternCursor.html">Duplex.Applications.PatternCursor</a></li>
  <li><a href="../modules/Duplex.Applications.PatternSequence.html">Duplex.Applications.PatternSequence</a></li>
  <li><a href="../modules/Duplex.Applications.Recorder.html">Duplex.Applications.Recorder</a></li>
  <li><a href="../modules/Duplex.Applications.Repeater.html">Duplex.Applications.Repeater</a></li>
  <li><a href="../modules/Duplex.Applications.Rotate.html">Duplex.Applications.Rotate</a></li>
  <li><a href="../modules/Duplex.Applications.StepSequencer.html">Duplex.Applications.StepSequencer</a></li>
  <li><a href="../modules/Duplex.Applications.SwitchConfiguration.html">Duplex.Applications.SwitchConfiguration</a></li>
  <li><a href="../modules/Duplex.Applications.TestPad.html">Duplex.Applications.TestPad</a></li>
  <li><a href="../modules/Duplex.Applications.TrackSelector.html">Duplex.Applications.TrackSelector</a></li>
  <li><a href="../modules/Duplex.Applications.Transport.html">Duplex.Applications.Transport</a></li>
  <li><a href="../modules/Duplex.Applications.UIButtonTest.html">Duplex.Applications.UIButtonTest</a></li>
  <li><a href="../modules/Duplex.Applications.XYPad.html">Duplex.Applications.XYPad</a></li>
  <li><a href="../modules/Duplex.Automation.html">Duplex.Automation</a></li>
  <li><a href="../modules/Duplex.Browser.html">Duplex.Browser</a></li>
  <li><a href="../modules/Duplex.BrowserProcess.html">Duplex.BrowserProcess</a></li>
  <li><a href="../modules/Duplex.Canvas.html">Duplex.Canvas</a></li>
  <li><a href="../modules/Duplex.CanvasPoint.html">Duplex.CanvasPoint</a></li>
  <li><a href="../modules/Duplex.ControlMap.html">Duplex.ControlMap</a></li>
  <li><a href="../modules/Duplex.Device.html">Duplex.Device</a></li>
  <li><a href="../modules/Duplex.Display.html">Duplex.Display</a></li>
  <li><a href="../modules/Duplex.Globals.html">Duplex.Globals</a></li>
  <li><a href="../modules/Duplex.Message.html">Duplex.Message</a></li>
  <li><a href="../modules/Duplex.MessageStream.html">Duplex.MessageStream</a></li>
  <li><a href="../modules/Duplex.MidiDevice.html">Duplex.MidiDevice</a></li>
  <li><a href="../modules/Duplex.OscClient.html">Duplex.OscClient</a></li>
  <li><a href="../modules/Duplex.OscDevice.html">Duplex.OscDevice</a></li>
  <li><a href="../modules/Duplex.OscVoiceMgr.html">Duplex.OscVoiceMgr</a></li>
  <li><a href="../modules/Duplex.Preferences.html">Duplex.Preferences</a></li>
  <li><a href="../modules/Duplex.ProcessSlicer.html">Duplex.ProcessSlicer</a></li>
  <li><a href="../modules/Duplex.RoamingDSP.html">Duplex.RoamingDSP</a></li>
  <li><a href="../modules/Duplex.Scheduler.html">Duplex.Scheduler</a></li>
  <li><a href="../modules/Duplex.StateController.html">Duplex.StateController</a></li>
  <li><a href="../modules/Duplex.UIButton.html">Duplex.UIButton</a></li>
  <li><a href="../modules/Duplex.UIButtonStrip.html">Duplex.UIButtonStrip</a></li>
  <li><a href="../modules/Duplex.UIComponent.html">Duplex.UIComponent</a></li>
  <li><a href="../modules/Duplex.UIKey.html">Duplex.UIKey</a></li>
  <li><a href="../modules/Duplex.UIKeyPressure.html">Duplex.UIKeyPressure</a></li>
  <li><a href="../modules/Duplex.UILabel.html">Duplex.UILabel</a></li>
  <li><a href="../modules/Duplex.UIPad.html">Duplex.UIPad</a></li>
  <li><a href="../modules/Duplex.UIPitchBend.html">Duplex.UIPitchBend</a></li>
  <li><a href="../modules/Duplex.UISlider.html">Duplex.UISlider</a></li>
  <li><a href="../modules/Duplex.UISpinner.html">Duplex.UISpinner</a></li>
  <li><a href="../modules/Duplex.WidgetHooks.html">Duplex.WidgetHooks</a></li>
  <li><a href="../modules/Duplex.WidgetKeyboard.html">Duplex.WidgetKeyboard</a></li>
  <li><a href="../modules/Duplex.html">Duplex</a></li>
  <li><a href="../modules/main.html">main</a></li>
</ul>

</div>

<div id="content">

<h1>Module <code>Duplex.Applications.Keyboard</code></h1>
<p>A replacement of the standard Renoise keyboard, supporting for MIDI and OSC.</p>
<p>

<p>Inheritance: <a href="../modules/Duplex.Application.html#">Duplex.Application</a> > Duplex.Application.Keyboard </p>

<h3>Features</h3>

<ul>
    <li>Integrate with standard MIDI Keyboard or Pad/Grid controller</li>
    <li>Produce keyboard splits and customize the behaviour</li>
    <li>Route specific splits to specific instruments and/or tracks</li>
</ul>

<h3>In more details</h3>

<p>The Keyboard application can be used as a standard keyboard (visulized as black &amp; white keys in the virtual control surface), or as individually-mapped keys/pads, suitable for grid and pad controllers.</p>

<p>When you are using the application in the standard keyboard mode, it might receive pitch bend and channel pressure information from the device, which can then be A) ignored, B) broadcast as MIDI (unchanged), C) or routed internally to any MIDI CC message (this in turn means that you can easily use the native MIDI mapping in Renoise to map the pitch bend to any parameter) </p>

<p>In grid mode, the Keyboard application is able to visualize the currently selected instrument's keyzone/sample mappings in realtime. This makes it a lot easier to see exactly where each sound is located, and even works as you are moving mappings around, or transposing the keyboard (octave up/down). Also, all of the UISlider mappings (volume, octave, pitch bend, etc.) support grid mode, as their mappings can be mapped to buttons just as easily as they can be mapped to a physical slider or fader. </p>

<p>Furthermore, since we are using internally-triggered notes we have the ability to trigger notes inside a specific track, using a specific instrument.
The default setting is identical to the standard behaviour in Renoise, and simply uses the currently selected track/instrument. But it's possible to select any track or instrument using the options "Active track/instr.", choosing any number between 1-64 (a planned feature is to "lock" the track or instrument by assigning a special name to it, something which has not made it into this initial release).</p>

<p>Finally, you can stack multiple Keyboard applications to control/trigger multiple instruments with a single master keyboard. The "MIDI-Keyboard" device comes with a configuration that demonstrate this ("Stacked Keys"), in which three instrument are triggered, each with different velocity settings.</p>


<h3>Prerequisites</h3>

<p>  The Keyboard application will not work unless you have enabled the internal OSC server in Renoise (Renoise prefereces -> OSC settings). It should be set to "UPD" protocol, and use the same port as specified in Duplex/Globals.lua (by default, this is set to the same value as Renoise, "8000").</p>


<h3>Discuss</h3>

<p>Tool discussion is located on the <a href="http://forum.renoise.com/index.php?/topic/33806-new-tool-duplex-keyboard/">Renoise forum</a></p>


<h3>Changes</h3>

<p>  0.99.4</p>
<pre><code>- Support for Renoise 3 trigger options (hold/mono modes)
- Custom grid layouts (harmonic, isomorphic layout and piano emulation)
</code></pre>

<p>  0.99.2</p>
<pre><code>- Adapted to UIKey changes
- New mapping: mod_wheel
</code></pre>

<p>  0.98.32</p>
<pre><code>- TWEAK: velocity now is set to an explicit value, or synced to Renoise keyboard
  velocity will output a fixed velocity (previously it was relative to messages)
</code></pre>

<p>  0.98.16</p>
<pre><code>- Display message on how to enable OSC server (first time only)
</code></pre>

<p>  0.98.15</p>
<pre><code>- New option: “Keyboard Mode”, choose which notes (if any) to trigger
</code></pre>

<p>  0.98 </p>
<pre><code>- First release
</code></pre>

</p>


<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
	<tr>
	<td class="name" nowrap><a href="#__init">__init (VarArg)</a></td>
	<td class="summary">Constructor method</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#trigger">trigger (note_on, instr_idx, pitch, velocity, grid_index)</a></td>
	<td class="summary">Trigger notes using the internal voice manager (OSC server)</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#all_notes_off">all_notes_off ()</a></td>
	<td class="summary">stop all playing voices</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#inside_note_range">inside_note_range (pitch)</a></td>
	<td class="summary">Test whether a given pitch is inside the specified note-range</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#get_nth_note">get_nth_note (idx)</a></td>
	<td class="summary">Retrieve the number of semitones for the note in the current scale</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#restrict_pitch_to_scale">restrict_pitch_to_scale (pitch)</a></td>
	<td class="summary">Restrict pitches to the ones allowed by the scale
 (for example, when playing E in natural minor it becomes D#)</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#_maintain_held_notes">_maintain_held_notes (voice_count, instr_idx, grid_index, velocity)</a></td>
	<td class="summary">Call this function immediately after triggering or releasing notes
 it will keep a record of notes triggered with the "hold" option</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#voicemgr_callback">voicemgr_callback ()</a></td>
	<td class="summary">Invoked by our voice manager</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#on_scale_change">on_scale_change ()</a></td>
	<td class="summary">Rebuild &amp; retrigger (held) notes when changing the scale ...</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#send_midi">send_midi (msg)</a></td>
	<td class="summary">send MIDI message using the internal OSC server</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#start_app">start_app ()</a></td>
	<td class="summary">inherited from Application</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#stop_app">stop_app ()</a></td>
	<td class="summary">inherited from Application</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#on_idle">on_idle ()</a></td>
	<td class="summary">inherited from Application</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#_build_app">_build_app ()</a></td>
	<td class="summary">inherited from Application</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#obtain_octave">obtain_octave ()</a></td>
	<td class="summary">called when application is first started</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#obtain_track">obtain_track ()</a></td>
	<td class="summary">called when application is first started</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#obtain_instr">obtain_instr ()</a></td>
	<td class="summary">called when application is first started</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#obtain_volume">obtain_volume ()</a></td>
	<td class="summary">called when application is first started</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#set_grid_layout">set_grid_layout (val)</a></td>
	<td class="summary">set<em>grid</em>layout() - choose between available layout classes</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#set_octave">set_octave (val, skip_option)</a></td>
	<td class="summary">set_octave() - sets the current octave</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#set_track">set_track (val, skip_option)</a></td>
	<td class="summary">switch to the selected track, optionally update options</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#set_instr">set_instr (instr_idx, skip_option)</a></td>
	<td class="summary">switch to the selected instrument, optionally update options</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#set_upper_boundary">set_upper_boundary (pitch)</a></td>
	<td class="summary">set the upper note on the keyboard</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#set_lower_boundary">set_lower_boundary (pitch)</a></td>
	<td class="summary">set the lower note on the keyboard</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#set_boundaries">set_boundaries ()</a></td>
	<td class="summary">update the upper/lower boundaries of the virtual keyboard</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#set_volume">set_volume (val, skip_option)</a></td>
	<td class="summary">set_octave() - sets the current volume</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#update_octave_controls">update_octave_controls ()</a></td>
	<td class="summary">update display of octave controls</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#update_track_controls">update_track_controls ()</a></td>
	<td class="summary">update display of track controls</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#update_instr_controls">update_instr_controls ()</a></td>
	<td class="summary">update display of instrument controls</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#update_cycle_controls">update_cycle_controls ()</a></td>
	<td class="summary">update display of layout cycler</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#update_volume_controls">update_volume_controls ()</a></td>
	<td class="summary">update display of volume controls</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#cache_grid">cache_grid ()</a></td>
	<td class="summary">preprocess/cache the grid</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#get_instrument_index">get_instrument_index ()</a></td>
	<td class="summary">obtain the current instrument
 this method should ALWAYS be able to produce an instrument
 (fall back on the currently selected instrument if none was matched)
 return int,bool</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#get_track_index">get_track_index ()</a></td>
	<td class="summary">obtain the current track
 this method should ALWAYS be able to produce a valid track index
 (fall back on the currently selected track if none was matched)
 return int</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#on_new_document">on_new_document ()</a></td>
	<td class="summary">inherited from Application</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#_attach_to_song">_attach_to_song ()</a></td>
	<td class="summary">attach notifier to the song, handle changes</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#attach_to_instrument">attach_to_instrument ()</a></td>
	<td class="summary">attach notifiers to selected instrument
 (watch for swapped keyzones, keyzone note-ranges)</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#_remove_notifiers">_remove_notifiers (observables)</a></td>
	<td class="summary">brute force method for removing observables</td>
	</tr>
</table>
<h2><a href="#Tables">Tables</a></h2>
<table class="function_list">
	<tr>
	<td class="name" nowrap><a href="#self._controls">self._controls</a></td>
	<td class="summary">the various UIComponents</td>
	</tr>
</table>
<h2><a href="#Fields">Fields</a></h2>
<table class="function_list">
	<tr>
	<td class="name" nowrap><a href="#self.curr_octave">self.curr_octave</a></td>
	<td class="summary">octave</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self.curr_volume">self.curr_volume</a></td>
	<td class="summary">volume</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self.curr_track">self.curr_track</a></td>
	<td class="summary">track index</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self.curr_instr">self.curr_instr</a></td>
	<td class="summary">instrument index</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self.scale_mode">self.scale_mode</a></td>
	<td class="summary">instrument scale</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self.scale_key">self.scale_key</a></td>
	<td class="summary">instrument scale</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self.lower_note">self.lower_note</a></td>
	<td class="summary">lower note</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self.upper_note">self.upper_note</a></td>
	<td class="summary">upper note</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self.grid_w">self.grid_w</a></td>
	<td class="summary">grid width</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self.grid_h">self.grid_h</a></td>
	<td class="summary">grid height</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self.voice_mgr">self.voice_mgr</a></td>
	<td class="summary">voice manager</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self._key_args">self._key_args</a></td>
	<td class="summary">control-map parameters</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self._instr_observables">self._instr_observables</a></td>
	<td class="summary">instrument observables</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self.held_notes">self.held_notes</a></td>
	<td class="summary">table of currently playing, hold-mode triggered notes</td>
	</tr>
	<tr>
	<td class="name" nowrap><a href="#self.pressed_buttons">self.pressed_buttons</a></td>
	<td class="summary">table of pressed buttons</td>
	</tr>
</table>

<br/>
<br/>


    <h2><a name="Functions"></a>Functions</h2>
    <dl class="function">
    <dt>
    <a name = "__init"></a>
    <strong>__init (VarArg)</strong>
    </dt>
    <dd>
    Constructor method


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">VarArg</span>
        )
        </li>
    </ul>



    <h3>See also:</h3>
    <ul>
         <a href="../modules/Duplex.Application.html#">Duplex.Application</a>
    </ul>


</dd>
    <dt>
    <a name = "trigger"></a>
    <strong>trigger (note_on, instr_idx, pitch, velocity, grid_index)</strong>
    </dt>
    <dd>
    Trigger notes using the internal voice manager (OSC server)


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">note_on</span>
         (bool), whether to send note-on/off
        </li>
        <li><span class="parameter">instr_idx</span>
         (int)
        </li>
        <li><span class="parameter">pitch</span>
         (int) 0-120
        </li>
        <li><span class="parameter">velocity</span>
         (int) 0-127
        </li>
        <li><span class="parameter">grid_index</span>
         (bool), when triggered from grid (optional)
        </li>
    </ul>

    <h3>Returns:</h3>
    <ol>
        <li>
        true when note was triggered</li>
        <li>
        instr_idx the target instrument</li>
    </ol>




</dd>
    <dt>
    <a name = "all_notes_off"></a>
    <strong>all_notes_off ()</strong>
    </dt>
    <dd>
    stop all playing voices







</dd>
    <dt>
    <a name = "inside_note_range"></a>
    <strong>inside_note_range (pitch)</strong>
    </dt>
    <dd>
    Test whether a given pitch is inside the specified note-range


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">pitch</span>
         (int) note pitch
        </li>
    </ul>





</dd>
    <dt>
    <a name = "get_nth_note"></a>
    <strong>get_nth_note (idx)</strong>
    </dt>
    <dd>
    Retrieve the number of semitones for the note in the current scale


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">idx</span>
         (int)
        </li>
    </ul>





</dd>
    <dt>
    <a name = "restrict_pitch_to_scale"></a>
    <strong>restrict_pitch_to_scale (pitch)</strong>
    </dt>
    <dd>
    Restrict pitches to the ones allowed by the scale
 (for example, when playing E in natural minor it becomes D#)


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">pitch</span>



        </li>
    </ul>





</dd>
    <dt>
    <a name = "_maintain_held_notes"></a>
    <strong>_maintain_held_notes (voice_count, instr_idx, grid_index, velocity)</strong>
    </dt>
    <dd>
    Call this function immediately after triggering or releasing notes
 it will keep a record of notes triggered with the "hold" option


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">voice_count</span>
         (int) the number of voices prior to the trigger/release
        </li>
        <li><span class="parameter">instr_idx</span>
         (int)
        </li>
        <li><span class="parameter">grid_index</span>
         (int, optional) remove only notes triggered by this button
        </li>
        <li><span class="parameter">velocity</span>
         (int)
        </li>
    </ul>





</dd>
    <dt>
    <a name = "voicemgr_callback"></a>
    <strong>voicemgr_callback ()</strong>
    </dt>
    <dd>
    Invoked by our voice manager







</dd>
    <dt>
    <a name = "on_scale_change"></a>
    <strong>on_scale_change ()</strong>
    </dt>
    <dd>
    Rebuild &amp; retrigger (held) notes when changing the scale ...







</dd>
    <dt>
    <a name = "send_midi"></a>
    <strong>send_midi (msg)</strong>
    </dt>
    <dd>
    send MIDI message using the internal OSC server


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">msg</span>
         (table) MIDI message with three bytes
        </li>
    </ul>





</dd>
    <dt>
    <a name = "start_app"></a>
    <strong>start_app ()</strong>
    </dt>
    <dd>
    inherited from Application



    <h3>Returns:</h3>
    <ol>

        bool or nil
    </ol>


    <h3>See also:</h3>
    <ul>
         <a href="../modules/Duplex.Application.html#start_app">Duplex.Application.start_app</a>
    </ul>


</dd>
    <dt>
    <a name = "stop_app"></a>
    <strong>stop_app ()</strong>
    </dt>
    <dd>
    inherited from Application





    <h3>See also:</h3>
    <ul>
         <a href="../modules/Duplex.Application.html#stop_app">Duplex.Application.stop_app</a>
    </ul>


</dd>
    <dt>
    <a name = "on_idle"></a>
    <strong>on_idle ()</strong>
    </dt>
    <dd>
    inherited from Application





    <h3>See also:</h3>
    <ul>
         <a href="../modules/Duplex.Application.html#on_idle">Duplex.Application.on_idle</a>
    </ul>


</dd>
    <dt>
    <a name = "_build_app"></a>
    <strong>_build_app ()</strong>
    </dt>
    <dd>
    inherited from Application



    <h3>Returns:</h3>
    <ol>

        bool
    </ol>


    <h3>See also:</h3>
    <ul>
         <a href="../modules/Duplex.Application.html#_build_app">Duplex.Application._build_app</a>
    </ul>


</dd>
    <dt>
    <a name = "obtain_octave"></a>
    <strong>obtain_octave ()</strong>
    </dt>
    <dd>
    called when application is first started







</dd>
    <dt>
    <a name = "obtain_track"></a>
    <strong>obtain_track ()</strong>
    </dt>
    <dd>
    called when application is first started







</dd>
    <dt>
    <a name = "obtain_instr"></a>
    <strong>obtain_instr ()</strong>
    </dt>
    <dd>
    called when application is first started







</dd>
    <dt>
    <a name = "obtain_volume"></a>
    <strong>obtain_volume ()</strong>
    </dt>
    <dd>
    called when application is first started







</dd>
    <dt>
    <a name = "set_grid_layout"></a>
    <strong>set_grid_layout (val)</strong>
    </dt>
    <dd>
    set<em>grid</em>layout() - choose between available layout classes


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">val</span>
         (int), the index of the layout (as listed in options)
        </li>
    </ul>

    <h3>Returns:</h3>
    <ol>

        bool, false when initialization of class failed
    </ol>




</dd>
    <dt>
    <a name = "set_octave"></a>
    <strong>set_octave (val, skip_option)</strong>
    </dt>
    <dd>
    set_octave() - sets the current octave


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">val</span>
         (int), between 0 and 8
        </li>
        <li><span class="parameter">skip_option</span>
         (bool) set this to skip setting option
        </li>
    </ul>





</dd>
    <dt>
    <a name = "set_track"></a>
    <strong>set_track (val, skip_option)</strong>
    </dt>
    <dd>
    switch to the selected track, optionally update options


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">val</span>
         (int), track index
        </li>
        <li><span class="parameter">skip_option</span>
         (bool) set this to skip setting option
        </li>
    </ul>





</dd>
    <dt>
    <a name = "set_instr"></a>
    <strong>set_instr (instr_idx, skip_option)</strong>
    </dt>
    <dd>
    switch to the selected instrument, optionally update options


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">instr_idx</span>
         (int)
        </li>
        <li><span class="parameter">skip_option</span>
         (bool) set this to skip setting option
        </li>
    </ul>





</dd>
    <dt>
    <a name = "set_upper_boundary"></a>
    <strong>set_upper_boundary (pitch)</strong>
    </dt>
    <dd>
    set the upper note on the keyboard


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">pitch</span>
         (int) note pitch
        </li>
    </ul>





</dd>
    <dt>
    <a name = "set_lower_boundary"></a>
    <strong>set_lower_boundary (pitch)</strong>
    </dt>
    <dd>
    set the lower note on the keyboard


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">pitch</span>
         (int) note pitch
        </li>
    </ul>





</dd>
    <dt>
    <a name = "set_boundaries"></a>
    <strong>set_boundaries ()</strong>
    </dt>
    <dd>
    update the upper/lower boundaries of the virtual keyboard







</dd>
    <dt>
    <a name = "set_volume"></a>
    <strong>set_volume (val, skip_option)</strong>
    </dt>
    <dd>
    set_octave() - sets the current volume


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">val</span>
         (int), between 0 and 127
        </li>
        <li><span class="parameter">skip_option</span>
         (bool) set this to skip setting option
        </li>
    </ul>





</dd>
    <dt>
    <a name = "update_octave_controls"></a>
    <strong>update_octave_controls ()</strong>
    </dt>
    <dd>
    update display of octave controls







</dd>
    <dt>
    <a name = "update_track_controls"></a>
    <strong>update_track_controls ()</strong>
    </dt>
    <dd>
    update display of track controls







</dd>
    <dt>
    <a name = "update_instr_controls"></a>
    <strong>update_instr_controls ()</strong>
    </dt>
    <dd>
    update display of instrument controls







</dd>
    <dt>
    <a name = "update_cycle_controls"></a>
    <strong>update_cycle_controls ()</strong>
    </dt>
    <dd>
    update display of layout cycler







</dd>
    <dt>
    <a name = "update_volume_controls"></a>
    <strong>update_volume_controls ()</strong>
    </dt>
    <dd>
    update display of volume controls







</dd>
    <dt>
    <a name = "cache_grid"></a>
    <strong>cache_grid ()</strong>
    </dt>
    <dd>
    preprocess/cache the grid





    <h3>See also:</h3>
    <ul>
         <a href="../modules/Duplex.Applications.Keyboard.GridLayout.html#">Duplex.Applications.Keyboard.GridLayout</a>
    </ul>


</dd>
    <dt>
    <a name = "get_instrument_index"></a>
    <strong>get_instrument_index ()</strong>
    </dt>
    <dd>
    obtain the current instrument
 this method should ALWAYS be able to produce an instrument
 (fall back on the currently selected instrument if none was matched)
 return int,bool







</dd>
    <dt>
    <a name = "get_track_index"></a>
    <strong>get_track_index ()</strong>
    </dt>
    <dd>
    obtain the current track
 this method should ALWAYS be able to produce a valid track index
 (fall back on the currently selected track if none was matched)
 return int







</dd>
    <dt>
    <a name = "on_new_document"></a>
    <strong>on_new_document ()</strong>
    </dt>
    <dd>
    inherited from Application





    <h3>See also:</h3>
    <ul>
         <a href="../modules/Duplex.Application.html#on_new_document">Duplex.Application.on_new_document</a>
    </ul>


</dd>
    <dt>
    <a name = "_attach_to_song"></a>
    <strong>_attach_to_song ()</strong>
    </dt>
    <dd>
    attach notifier to the song, handle changes







</dd>
    <dt>
    <a name = "attach_to_instrument"></a>
    <strong>attach_to_instrument ()</strong>
    </dt>
    <dd>
    attach notifiers to selected instrument
 (watch for swapped keyzones, keyzone note-ranges)







</dd>
    <dt>
    <a name = "_remove_notifiers"></a>
    <strong>_remove_notifiers (observables)</strong>
    </dt>
    <dd>
    brute force method for removing observables


    <h3>Parameters:</h3>
    <ul>
        <li><span class="parameter">observables</span>

<ul>
    <li>list of observables</li>
</ul>

        </li>
    </ul>





</dd>
</dl>
    <h2><a name="Tables"></a>Tables</h2>
    <dl class="function">
    <dt>
    <a name = "self._controls"></a>
    <strong>self._controls</strong>
    </dt>
    <dd>
    the various UIComponents







</dd>
</dl>
    <h2><a name="Fields"></a>Fields</h2>
    <dl class="function">
    <dt>
    <a name = "self.curr_octave"></a>
    <strong>self.curr_octave</strong>
    </dt>
    <dd>
    octave







</dd>
    <dt>
    <a name = "self.curr_volume"></a>
    <strong>self.curr_volume</strong>
    </dt>
    <dd>
    volume







</dd>
    <dt>
    <a name = "self.curr_track"></a>
    <strong>self.curr_track</strong>
    </dt>
    <dd>
    track index







</dd>
    <dt>
    <a name = "self.curr_instr"></a>
    <strong>self.curr_instr</strong>
    </dt>
    <dd>
    instrument index







</dd>
    <dt>
    <a name = "self.scale_mode"></a>
    <strong>self.scale_mode</strong>
    </dt>
    <dd>
    instrument scale







</dd>
    <dt>
    <a name = "self.scale_key"></a>
    <strong>self.scale_key</strong>
    </dt>
    <dd>
    instrument scale







</dd>
    <dt>
    <a name = "self.lower_note"></a>
    <strong>self.lower_note</strong>
    </dt>
    <dd>
    lower note







</dd>
    <dt>
    <a name = "self.upper_note"></a>
    <strong>self.upper_note</strong>
    </dt>
    <dd>
    upper note







</dd>
    <dt>
    <a name = "self.grid_w"></a>
    <strong>self.grid_w</strong>
    </dt>
    <dd>
    grid width







</dd>
    <dt>
    <a name = "self.grid_h"></a>
    <strong>self.grid_h</strong>
    </dt>
    <dd>
    grid height







</dd>
    <dt>
    <a name = "self.voice_mgr"></a>
    <strong>self.voice_mgr</strong>
    </dt>
    <dd>
    voice manager







</dd>
    <dt>
    <a name = "self._key_args"></a>
    <strong>self._key_args</strong>
    </dt>
    <dd>
    control-map parameters







</dd>
    <dt>
    <a name = "self._instr_observables"></a>
    <strong>self._instr_observables</strong>
    </dt>
    <dd>
    instrument observables







</dd>
    <dt>
    <a name = "self.held_notes"></a>
    <strong>self.held_notes</strong>
    </dt>
    <dd>
    table of currently playing, hold-mode triggered notes







</dd>
    <dt>
    <a name = "self.pressed_buttons"></a>
    <strong>self.pressed_buttons</strong>
    </dt>
    <dd>
    table of pressed buttons







</dd>
</dl>


</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.2</a></i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>
